package 初识线程;

import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.*;

public class Main {

    // 初识线程
    private static class MyThread extends Thread {
        @Override
        public void run() {
            Random random = new Random();
            while (true) {
                System.out.println(Thread.currentThread().getName());
                try {
                    Thread.sleep(random.nextInt(10));
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }


    public static void main1(String[] args) {
        MyThread t1 = new MyThread();
        MyThread t2 = new MyThread();
        MyThread t3 = new MyThread();
        MyThread t4 = new MyThread();

        t1.start();
        t2.start();
        t3.start();
        t4.start();


        Random random = new Random();
        while (true) {
            System.out.println(Thread.currentThread().getName());
            try {
                Thread.sleep(random.nextInt(10));
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }


    // 转账
    private static class MyRunnable implements Runnable {
        public volatile boolean isQuit = false;

        @Override
        public void run() {
            while (!isQuit) {
                System.out.println(Thread.currentThread().getName() + ": " + "我忙着转账呢!");

                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
            System.out.println(Thread.currentThread().getName() + "溜了");
        }
    }

    public static void main2(String[] args) throws InterruptedException {
        MyRunnable myRunnable = new MyRunnable();
        Thread t = new Thread(myRunnable, "小明");
        System.out.println(Thread.currentThread().getName() + ": " + "通知小明开始交易!");
        t.start();
        Thread.sleep(5 * 1000);
        System.out.println("交易取消~");
        myRunnable.isQuit = true;
    }

    public static void main(String[] args) {
        for (Thread.State value : Thread.State.values()) {
            System.out.println(value);
        }
    }

}


class Singleton {
    private Singleton singleton = null;

    public Singleton getSingleton() {
        if (singleton == null) {
            synchronized (this) {
                if (singleton == null) {
                    singleton = new Singleton();
                }
            }
        }
        return singleton;
    }


    private Singleton() {

    }
}


class BlockingQueueMain {
    public static void main(String[] args) {
        BlockingQueue<Integer> blockingQueue = new LinkedBlockingQueue<>(10);

        Thread consumer = new Thread(() -> {
            try {
                while (true) {
                    Integer take = blockingQueue.take();
                    System.out.println("消费消息: " + take);
                    Thread.sleep(1000);
                }
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        });

        Thread produce = new Thread(() -> {
            int count = 0;
            try {
                while (true) {
                    System.out.println("生产消息: " + count);
                    blockingQueue.put(count++);
                    Thread.sleep(500);
                }
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        });


        consumer.start();
        produce.start();

    }
}

class MyBlockingQueue {
    private volatile int size;
    private int[] nums;
    private volatile int head;
    private volatile int tail;

    public MyBlockingQueue(int size) {
        this.size = size + 1;
        nums = new int[this.size];
        head = tail = 0;
    }

    public boolean empty() {
        return head == tail;
    }

    public boolean full() {
        return (tail + 1) % size == head;
    }


    public void put(int val) {
        synchronized (this) {
            while (full()) {
                try {
                    wait();
                } catch (InterruptedException e) {
                }
            }

            nums[tail] = val;
            tail = (tail + 1) % size;
            notifyAll();
        }
    }

    public int take() {
        synchronized (this) {
            while (empty()) {
                try {
                    wait();
                } catch (InterruptedException e) {
                }
            }

            int ret = nums[head];
            head = (head + 1) % size;

            notifyAll();
            return ret;
        }
    }


    public static void main(String[] args) {
        MyBlockingQueue blockingQueue = new MyBlockingQueue(10);

        Thread consumer = new Thread(() -> {
            try {
                while (true) {
                    int take = blockingQueue.take();
                    System.out.println("消费消息: " + take);
                    Thread.sleep(1000);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        });

        Thread produce = new Thread(() -> {
            int count = 0;
            try {
                while (true) {
                    System.out.println("生产消息: " + count);
                    blockingQueue.put(count++);
                    Thread.sleep(500);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        });


        consumer.start();
        produce.start();

    }

}


class MyTimer {
    private static class MyTimerTask implements Comparable<MyTimerTask> {
        private Runnable task;
        private long time;

        public MyTimerTask(Runnable task, long time) {
            this.task = task;
            this.time = time + System.currentTimeMillis();
        }


        @Override
        public int compareTo(MyTimerTask o) {
            return (int) (time - o.time);
        }
    }

    private PriorityBlockingQueue<MyTimerTask> timerTasksQueue = new PriorityBlockingQueue<>();

    private Object waitBox = new Object();


    public MyTimer() {
        Thread t = new Thread(() -> {
            try {
                while (true) {
                    MyTimerTask task = timerTasksQueue.take();
                    long nowTime = System.currentTimeMillis();
                    if (nowTime > task.time) {
                        Thread tmp = new Thread(task.task);
                        tmp.start();
                    } else {
                        timerTasksQueue.put(task);
                        synchronized (waitBox) {
                            waitBox.wait(task.time - nowTime);
                        }
                    }
                }
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        });
        t.start();
    }


    public void schedule(Runnable task, long time) {
        timerTasksQueue.put(new MyTimerTask(task, time));
        synchronized (waitBox) {
            waitBox.notify();
        }
    }

    public static void main(String[] args) {
        MyTimer myTimer = new MyTimer();
        myTimer.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("hello word");
            }
        }, 1000);
    }

    public static void main1(String[] args) {
        Timer timer = new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                System.out.println("hello word!" + LocalDateTime.now());
            }
        }, 20); // 20毫秒后执行一次

        // 让主线程暂停较短时间，确保任务能执行
        try {
            Thread.sleep(500); // 暂停500毫秒
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        // 如果需要重复执行，可以使用 scheduleAtFixedRate
        Timer repeatTimer = new Timer();
        repeatTimer.scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                System.out.println("repeated hello word!" + LocalDateTime.now());
            }
        }, 20, 500); // 20毫秒后开始，每500毫秒执行一次

        // 让主线程保持运行一段时间
        try {
            Thread.sleep(5000); // 暂停5秒，观察多次执行效果
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}


class MyThreadPool {
    public static void main(String[] args) {
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        while (true) {
            executorService.submit(new Runnable() {
                @Override
                public void run() {
                    System.out.println("hello word: " + Thread.currentThread().getName());
                }
            });
        }
    }
}

class CustomThreadPool {
    private volatile boolean isShutdown;
    private Queue<Runnable> taskQueue;
    private int poolCoreSize;
    private Thread[] threads;

    private class WorkerThread extends Thread {

        public WorkerThread(String name) {
            super(name);
        }

        @Override
        public void run() {
            while (!isShutdown || !taskQueue.isEmpty()) {
                Runnable task = null;
                synchronized (taskQueue) {
                    while (taskQueue.isEmpty() && !isShutdown) {
                        try {
                            taskQueue.wait();
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        }
                    }
                    if (!taskQueue.isEmpty()) {
                        task = taskQueue.poll();
                    }
                }
                if (task != null) {
                    task.run();
                }
            }
        }
    }

    public CustomThreadPool(int poolCoreSize) {
        this.poolCoreSize = poolCoreSize;
        isShutdown = false;
        taskQueue = new LinkedList<>();
        threads = new WorkerThread[poolCoreSize];
        for (int i = 0; i < threads.length; i++) {
            threads[i] = new WorkerThread("Worker-" + i);
            threads[i].start();
        }
    }


    public void submit(Runnable task) {
        synchronized (taskQueue) {
            if (isShutdown) {
                throw new IllegalStateException("线程池已关闭");
            }
            taskQueue.add(task);
            taskQueue.notify();
        }
    }
    public void shutdown() {
        synchronized (taskQueue) {
            isShutdown = true;
            taskQueue.notifyAll();
        }
        for (Thread thread : threads) {
            try {
                thread.join();
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
    }
    public static void main(String[] args) {
        CustomThreadPool threadPool = new CustomThreadPool(10);

        for (int i = 0; i < 20; i++) {
            final int taskId = i;
            threadPool.submit(() -> {
                System.out.println("任务 " + taskId + " 正在执行，线程名: " + Thread.currentThread().getName());
                try {
                    Thread.sleep(1000); // 模拟任务执行时间
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    System.out.println("任务 " + taskId + " 被中断");
                }
                System.out.println("任务 " + taskId + " 执行完毕，线程名: " + Thread.currentThread().getName());
            });
        }

        // 关闭线程池
        threadPool.shutdown();
    }
}
